#include <avr/io.h>
#include <avr/iom644.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>

const char 		*byte_to_binary(int x);
void			USART_Init(unsigned int baudrate);
void			USART_Transmit(unsigned char data);
unsigned char 	USART_Not_Block_Receive(void);
void			USART_Send_String(char *buffer);

int
main(void)
{
	unsigned char aux;

	DDRA = 0x00;
	DDRB = 0xFF;

	USART_Init(25);
	PORTB = 0xDF;

	sei();

	while(1) {

		aux = PINA;

		if (aux != 0xFF) {
			if (aux == 0xDF) {
				USART_Init(25);
				PORTB = aux;
			}
			else if (aux == 0xBF) {
				USART_Init(12);
				PORTB = aux;
			}
			else if (aux == 0x7F) {
				USART_Init(6);
				PORTB = aux;
			}
		}
		_delay_ms(100);

	}
}

const char *byte_to_binary(int x)
{
    static char b[9];
    b[0] = '\0';
    int z;
    for (z = 256; z > 0; z >>= 1)
    {
        strcat(b, ((x & z) == z) ? "1" : "0");
    }
    return b;
}

void USART_Init(unsigned int baudrate)
{
	/* Se configura la veloridad de transferencia. */
	/* Ver tabla de valores. */

	UBRR0H = (unsigned char)(baudrate>>8);
	UBRR0L = (unsigned char)baudrate;

	/* Se habilita la transmision y la recepcion. */

	UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);

	/* Formato: 8data, 2stop bit. */

	UCSR0C = (1<<USBS0)|(3<<UCSZ00);

	/* Se habilitan las interrupciones. */

	sei();
}

void USART_Transmit(unsigned char data)
{
	/* Se espera a que el buffer este vacio. */

	while (!( UCSR0A & (1<<UDRE0))) {
		;
	}

	/* Se pone el caracter en buffer. */

	UDR0 = data;
}

unsigned char USART_Not_Block_Receive(void)
{
	/* Se lee el dato que hay en el buffer. Si no hay nada retorna 0. */

	if (UCSR0A & (1<<RXC0)) {
		return UDR0;
	}

	return 0;
}

void USART_Send_String(char *buffer)
{
	unsigned char aux = 0;

	/* Se mandan todos los caracteres que se reciben. */

	do
	{
		/* Se manda cada caracter. */
		aux = *buffer;
		buffer ++;
		USART_Transmit(aux);
	}
	while (aux != 0);
}

ISR(USART0_RX_vect){

	unsigned char aux;
	char string[60] = "";

	aux = USART_Not_Block_Receive();

	if (aux != 0) {
		sprintf (string, "ASCII - Valor: %x - Simbolo: %c - Bits: %s\n\r", aux, aux, byte_to_binary(aux));
		USART_Send_String(string);
	}
}
